home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectInput / DIConfig / flexinfobox.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  7.7 KB  |  321 lines

  1. //-----------------------------------------------------------------------------
  2. // File: flexinfobox.cpp
  3. //
  4. // Desc: Implements a simple text box that displays a text string.
  5. //       CFlexInfoBox is derived from CFlexWnd.  It is used by the page
  6. //       for displaying direction throughout the UI.  The strings are
  7. //       stored as resources.  The class has a static buffer which will
  8. //       be filled with the string by the resource API when needed.
  9. //
  10. // Copyright (C) Microsoft Corporation. All Rights Reserved.
  11. //-----------------------------------------------------------------------------
  12.  
  13. #include "common.hpp"
  14.  
  15. CFlexInfoBox::CFlexInfoBox() :
  16.     m_iCurIndex(-1),
  17.     m_rgbText(RGB(255,255,255)),
  18.     m_rgbBk(RGB(0,0,0)),
  19.     m_rgbSelText(RGB(0,0,255)),
  20.     m_rgbSelBk(RGB(0,0,0)),
  21.     m_rgbFill(RGB(0,0,255)),
  22.     m_rgbLine(RGB(0,255,255)),
  23.     m_hFont(NULL),
  24.     m_bVertSB(FALSE),
  25.     m_nSBWidth(11)
  26. {
  27.     m_TextRect.top = 0;
  28.     m_TextRect.left = 0;
  29.     m_TextRect.bottom = 0;
  30.     m_TextRect.right = 0;
  31. }
  32.  
  33. CFlexInfoBox::~CFlexInfoBox()
  34. {
  35. }
  36.  
  37. BOOL CFlexInfoBox::Create(HWND hParent, const RECT &rect, BOOL bVisible)
  38. {
  39.     if (!CFlexWnd::Create(hParent, rect, bVisible))
  40.         return FALSE;
  41.  
  42.     FLEXSCROLLBARCREATESTRUCT sbcs;
  43.     sbcs.dwSize = sizeof(FLEXSCROLLBARCREATESTRUCT);
  44.     sbcs.dwFlags = FSBF_VERT;
  45.     sbcs.min = 0;
  46.     sbcs.max = 3;
  47.     sbcs.page = 1;
  48.     sbcs.pos = 1;
  49.     sbcs.hWndParent = m_hWnd;
  50.     sbcs.hWndNotify = m_hWnd;
  51.     RECT rc = {0, 0, 1, 1};
  52.     sbcs.rect = rc;
  53.     sbcs.bVisible = FALSE;
  54.     return m_VertSB.Create(&sbcs);
  55. }
  56.  
  57. void CFlexInfoBox::SetText(int iIndex)
  58. {
  59.     if (iIndex == m_iCurIndex)
  60.         return;
  61.  
  62.     // Load the string from resource
  63.     LoadString(g_hModule, iIndex, m_tszText, MAX_PATH);
  64.  
  65.     // Calculate the rectangle for text
  66.     RECT titlerc;
  67.     m_TextRect = g_InfoWndRect;
  68.     OffsetRect(&m_TextRect, -m_TextRect.left, -m_TextRect.top);
  69.  
  70.     InflateRect(&m_TextRect, -1, -1);
  71.     titlerc = m_TextRect;
  72.     HDC hDC = CreateCompatibleDC(NULL);
  73.     if (hDC)
  74.     {
  75.         TCHAR tszResourceString[MAX_PATH];
  76.         LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
  77.         DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
  78.         m_TextRect.top = titlerc.bottom + 1;
  79.         m_TextWinRect = m_TextRect;
  80.         DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
  81.         if (m_TextRect.bottom + 1 > g_InfoWndRect.bottom - g_InfoWndRect.top)
  82.         {
  83.             // Text too long. We need a scroll bar.
  84.             m_TextRect.right -= m_nSBWidth;
  85.             DrawText(hDC, m_tszText, -1, &m_TextRect, DT_CENTER|DT_NOPREFIX|DT_CALCRECT|DT_WORDBREAK);
  86.             SetVertSB(TRUE);
  87.         } else
  88.             SetVertSB(FALSE);
  89.         DeleteDC(hDC);
  90.     }
  91.  
  92.     m_iCurIndex = iIndex;
  93.     Invalidate();
  94. }
  95.  
  96. void CFlexInfoBox::SetFont(HFONT hFont)
  97. {
  98.     m_hFont = hFont;
  99.  
  100.     if (m_hWnd == NULL)
  101.         return;
  102.  
  103.     Invalidate();
  104. }
  105.  
  106. void CFlexInfoBox::SetColors(COLORREF text, COLORREF bk, COLORREF seltext, COLORREF selbk, COLORREF fill, COLORREF line)
  107. {
  108.     m_rgbText = text;
  109.     m_rgbBk = bk;
  110.     m_rgbSelText = seltext;
  111.     m_rgbSelBk = selbk;
  112.     m_rgbFill = fill;
  113.     m_rgbLine = line;
  114.     m_VertSB.SetColors(m_rgbBk, m_rgbFill, m_rgbLine);
  115.  
  116.     Invalidate();
  117. }
  118.  
  119. void CFlexInfoBox::SetRect()
  120. {
  121.     if (m_hWnd == NULL)
  122.         return;
  123.  
  124.     RECT rect = GetRect();
  125.     SetWindowPos(m_hWnd, NULL, rect.left, rect.top, rect.right, rect.bottom, SWP_NOZORDER | SWP_NOMOVE);
  126. }
  127.  
  128. RECT CFlexInfoBox::GetRect(const RECT &rect)
  129. {
  130.     int h = GetTextHeight(m_hFont);
  131.     RECT ret = {rect.left, rect.top, rect.right, rect.top + h + 2};
  132.     return ret;
  133. }
  134.  
  135. RECT CFlexInfoBox::GetRect()
  136. {
  137.     RECT rect;
  138.     GetClientRect(&rect);
  139.     return GetRect(rect);
  140. }
  141.  
  142. void CFlexInfoBox::OnPaint(HDC hDC)
  143. {
  144.     HDC hBDC = NULL, hODC = NULL;
  145.     CBitmap *pbm = NULL;
  146.  
  147.     if (!InRenderMode())
  148.     {
  149.         hODC = hDC;
  150.         pbm = CBitmap::Create(GetClientSize(), RGB(0,0,0), hDC);
  151.         if (pbm != NULL)
  152.         {
  153.             hBDC = pbm->BeginPaintInto();
  154.             if (hBDC != NULL)
  155.             {
  156.                 hDC = hBDC;
  157.             }
  158.         }
  159.     }
  160.  
  161.     InternalPaint(hDC);
  162.  
  163.     if (!InRenderMode())
  164.     {
  165.         if (pbm != NULL)
  166.         {
  167.             if (hBDC != NULL)
  168.             {
  169.                 pbm->EndPaintInto(hBDC);
  170.                 pbm->Draw(hODC);
  171.             }
  172.             delete pbm;
  173.         }
  174.     }
  175. }
  176.  
  177. void CFlexInfoBox::InternalPaint(HDC hDC)
  178. {
  179.     TCHAR tszResourceString[MAX_PATH];
  180.     HGDIOBJ hPen = (HGDIOBJ)CreatePen(PS_SOLID, 1, m_rgbLine);
  181.     if (hPen != NULL)
  182.     {
  183.         HGDIOBJ hOldPen = SelectObject(hDC, hPen);
  184.  
  185.         HGDIOBJ hBrush = (HGDIOBJ)CreateSolidBrush(m_rgbBk);
  186.         if (hBrush != NULL)
  187.         {
  188.             HGDIOBJ hOldBrush = SelectObject(hDC, hBrush);
  189.  
  190.             RECT rect = {0,0,0,0}, titlerc;
  191.             GetClientRect(&rect);
  192.             titlerc = rect;
  193.             Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
  194.  
  195.             InflateRect(&rect, -1, -1);
  196.             SetBkMode(hDC, TRANSPARENT);
  197.  
  198.             LoadString(g_hModule, IDS_INFO_TITLE, tszResourceString, MAX_PATH);
  199.             // Draw the message text
  200.             SetTextColor(hDC, m_rgbText);
  201.             rect = m_TextRect;
  202.             // Offset the rectangle to account for scroll bar
  203.             if (m_bVertSB)
  204.             {
  205.                 OffsetRect(&rect, 0, -m_VertSB.GetPos());
  206.             }
  207.             DrawText(hDC, m_tszText, -1, &rect, DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
  208.  
  209.             GetClientRect(&rect);
  210.             InflateRect(&rect, -1, -1);
  211.             SetTextColor(hDC, m_rgbLine);  // User line color for Information title
  212.             // Get the title area rantangle
  213.             DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX|DT_CALCRECT);
  214.             // Adjust right edge position to old value
  215.             titlerc.right = rect.right + 1;
  216.             // Draw a rectangle around the title area.
  217.             Rectangle(hDC, titlerc.left, titlerc.top, titlerc.right, titlerc.bottom);
  218.             // Draw title text (Information)
  219.             DrawText(hDC, tszResourceString, -1, &titlerc, DT_CENTER|DT_NOPREFIX);
  220.  
  221.             SelectObject(hDC, hOldBrush);
  222.             DeleteObject(hBrush);
  223.         }
  224.  
  225.         SelectObject(hDC, hOldPen);
  226.         DeleteObject(hPen);
  227.     }
  228. }
  229.  
  230. void CFlexInfoBox::SetVertSB(BOOL bSet)
  231. {
  232.     if (!bSet && !m_bVertSB)
  233.         return;
  234.  
  235.     m_bVertSB = bSet;
  236.  
  237.     if (m_hWnd == NULL)
  238.         return;
  239.  
  240.     SetVertSB();
  241. }
  242.  
  243. void CFlexInfoBox::SetVertSB()
  244. {
  245.     if (m_bVertSB)
  246.     {
  247.         SetSBValues();
  248.         SIZE client = GetClientSize();
  249.         client.cy = m_TextWinRect.bottom - m_TextWinRect.top;
  250.         SetWindowPos(m_VertSB.m_hWnd, NULL, client.cx - m_nSBWidth - 1, m_TextRect.top, m_nSBWidth, client.cy - 1, SWP_NOZORDER);
  251.     }
  252.  
  253.     ShowWindow(m_VertSB.m_hWnd, m_bVertSB ? SW_SHOW : SW_HIDE);
  254. }
  255.  
  256. void CFlexInfoBox::SetSBValues()
  257. {
  258.     if (m_hWnd == NULL)
  259.         return;
  260.  
  261.     m_VertSB.SetValues(0, m_TextRect.bottom - m_TextRect.top, m_TextWinRect.bottom - m_TextWinRect.top, 0);
  262. }
  263.  
  264. void CFlexInfoBox::OnWheel(POINT point, WPARAM wParam)
  265. {
  266.     if (!m_bVertSB) return;
  267.  
  268.     if (m_VertSB.GetMin() == m_VertSB.GetMax()) return;
  269.  
  270.     int nPage = MulDiv(m_VertSB.GetPage(), 9, 10) >> 1;  // Half a page at a time
  271.  
  272.     if ((int)wParam >= 0)
  273.         m_VertSB.AdjustPos(-nPage);
  274.     else
  275.         m_VertSB.AdjustPos(nPage);
  276.  
  277.     Invalidate();
  278. }
  279.  
  280. LRESULT CFlexInfoBox::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  281. {
  282.     switch (msg)
  283.     {
  284.         case WM_FLEXVSCROLL:
  285.         {
  286.             int code = (int)wParam;
  287.             CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
  288.             if (!pSB)
  289.                 return 0;
  290.  
  291.             int nLine = 1;
  292.             int nPage = MulDiv(pSB->GetPage(), 9, 10);
  293.  
  294.             switch (code)
  295.             {
  296.                 case SB_LINEUP: pSB->AdjustPos(-nLine); break;
  297.                 case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
  298.                 case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
  299.                 case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
  300.                 case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
  301.                 case SB_ENDSCROLL:
  302.                     ::ReleaseCapture();
  303.                     break;
  304.             }
  305.  
  306.             Invalidate();
  307.             return 0;
  308.         }
  309.         default:
  310.             if (msg == WM_LBUTTONDOWN)
  311.             {
  312.                 HWND hWndParent;
  313.                 hWndParent = GetParent(hWnd);
  314.                 SendMessage(hWndParent, WM_UNHIGHLIGHT, 0, 0);  // Send click message to page to unhighlight callout
  315.             }
  316.             return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
  317.     }
  318.  
  319.     return 0;
  320. }
  321.